package client;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;

import security.Channel;
import security.HMACutil;

/**
 * Listenes to a TCP socket;
 * @author Gernot
 *
 */
public class ClientListenerTCP extends Thread{
    private Channel channel;
    String concatenatedListResponseForHmacCheck = null;
    boolean hmacRequest = false, clientList = false, hiddenRequest = false;

    public ClientListenerTCP(Channel channel) throws IOException {
        super();
        this.channel = channel;
        this.start();
    }

    public void stopListening() throws IOException{
        channel.close();
    }
    
    
    @Override
    public void run() {
        String str;
        try {
            while ( (str = channel.receive())!=null) {
                //System.out.println("RECEIVED:"+str);
                if (str.startsWith("Successfully logged in as ")){
                    Client.username = str.substring("Successfully logged in as ".length(), str.length()-1);
                    System.out.println(str);
                    Client.updateClientList();
                    Client.sendPendingSignedBids();
                } else if (str.startsWith("Successfully logged out as")){
                    Client.username = "";
                    System.out.println(str);
                    
                }else if (str.startsWith("!confirmed")){
                    Client.unblockClient();
                    System.out.println("GroupBid confirmed!");
                } else if (str.startsWith("!rejected")){
                    System.out.println(str.substring("!rejected ".length()));
                    Client.unblockClient();
                } else if (str.startsWith("!endlist")) {
                	if (concatenatedListResponseForHmacCheck != null) {
                		if (!HMACutil.checkHMAC(concatenatedListResponseForHmacCheck+str, Client.username)) {
                			String errMess = "HMAC-Error: The message seems to have been modified!";
                			if (!hmacRequest) {
                				hmacRequest = true;
                				errMess += " Requesting again...";
                    			if (!hiddenRequest)
                    				System.out.println(errMess);
                    			concatenatedListResponseForHmacCheck = "";
                    			if (clientList) {
                    				channel.send("!getClientList");
                    			} else {
                    				channel.send("!list");
                    			}
                			} else {
                    			if (!hiddenRequest)
                    				System.out.println(errMess);
                				concatenatedListResponseForHmacCheck = null;
                			}
                		} else {
                			if (!hiddenRequest)
                				System.out.println(concatenatedListResponseForHmacCheck.trim());
                			if (clientList)
                				parseClientList(concatenatedListResponseForHmacCheck);
                			concatenatedListResponseForHmacCheck = null;
                		}
                	}
                } else if (concatenatedListResponseForHmacCheck != null) {
                	concatenatedListResponseForHmacCheck += str + '\n';
                } else {
                    System.out.println(str);
                }

                if (Client.username != "" && concatenatedListResponseForHmacCheck == null)
                {
                	System.out.print(Client.username+"> ");
                }
            }
        } catch (IOException e) {
           System.out.println(e.getMessage());
           try {
            channel.close();
            } catch (IOException e1) {
               System.out.println(e.getMessage());
            } finally {
                Client.lostConnection();
            }
        } finally {
            System.out.println("ClientListenerTCP stopped!");
        }
        
    }
    
    
    private void parseClientList(String s) {
    	String[] entries = s.split("\n");
    	Client.clientList = new ClientAddress[entries.length - 1];
    	for (int i = 1; i < entries.length; i++) {
    		ClientAddress ca = new ClientAddress();
    		String[] parts = entries[i].split(" - ");
    		String[] connData = parts[0].split(":");
    		ca.setIp(connData[0]);
    		ca.setPort(Integer.parseInt(connData[1]));
    		ca.setUser(parts[1]);
    		Client.clientList[i-1] = ca;
    	}
    }
}
